package com.gc.baselib.base

import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.gc.baselib.base.event.NavigationEvent
import com.gc.baselib.base.event.ShutDownEvent
import com.gc.baselib.utils.SoftKeyBoardUtil
import com.gc.baselib.extend.ktxRunOnUiThreadDelay
import com.gc.logger.LogUtils

import org.greenrobot.eventbus.EventBus
import java.lang.reflect.ParameterizedType
import kotlin.system.exitProcess

/**
 * BaseActivity
 */
abstract class BaseActivity<V: ViewBinding,VM: BaseViewModel>: AppCompatActivity(),IBaseView,MVVMProvider<VM> {
    protected lateinit var mBinding: V
    protected lateinit var mViewModel: VM
    override fun onCreate(savedInstanceState: Bundle?) {
        requestedOrientation = setOrientation()
        super.onCreate(savedInstanceState)
        initBefore()
        mViewModel = initViewModel()
        if (intent != null && intent.extras != null) {
            initParams(intent.extras!!)
        }

        lifecycleOwner().lifecycle.addObserver(mViewModel)
        mBinding=initViewBinding()
        setContentView(mBinding.root)
        initView()
        initCommonEventBinding()
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        initObservable()
        initData()
//        LogUtils.d("framework","${this.javaClass.name}=======onCreate")
    }
    open fun initData() {

    }

    private fun initViewBinding(): V {
        val superClass = javaClass.genericSuperclass
        if (superClass is ParameterizedType) {
            val type = superClass.actualTypeArguments[0]
            val clazz = type as Class<V>
            val declaredMethod = clazz.getDeclaredMethod("inflate", LayoutInflater::class.java)
            val bingding = declaredMethod.invoke(null, layoutInflater)
            return bingding as V;
        }else{
            throw IllegalArgumentException("ParameterizedType error")
        }

    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        if (intent != null && intent.extras != null) {
            initNewIntentParams(intent.extras!!)
        }
        LogUtils.d("framework","${this.javaClass.name}=======onNewIntent")
    }
    open fun initObservable() {

    }

    private fun initCommonEventBinding() {
        mViewModel.commonEvent.finishEvent.observe(lifecycleOwner()
        ) { finish() }
        mViewModel.commonEvent.backEvent.observe(lifecycleOwner()
        ) { onBackPressed() }
        mViewModel.commonEvent.navEvent.observe(lifecycleOwner()
        ) { event: NavigationEvent ->
            if (event.navType == NavigationEvent.Nav_Type_Activity) {
                openNavigation(event)
            } else {
                //TODO
            }

        }
        mViewModel.commonEvent.toastEvent.observe(
            lifecycleOwner()
        ) { content: String? ->
            Toast.makeText(
                this,
                content,
                Toast.LENGTH_SHORT
            ).show()
        }
        mViewModel.commonEvent.softKeyBoardShowEvent.observe(lifecycleOwner()
        ) { aBoolean: Boolean ->
            if (aBoolean) {
                SoftKeyBoardUtil.showSoftKeyboard(this@BaseActivity)
            } else {
                SoftKeyBoardUtil.hideKeyBoard(this@BaseActivity)
            }
        }
    }

    open fun initBefore() {

    }
    open fun setOrientation():Int{
        return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    }

    override fun initParams(extras: Bundle) {
    }

    override fun initNewIntentParams(extras: Bundle) {
    }

    override fun initViewModel(): VM {
        val superClass = javaClass.genericSuperclass
        if (superClass is ParameterizedType) {
            val type = superClass.actualTypeArguments[1]
            val clazz = type as Class<VM>
            return  getViewModel(this,clazz)
        }else{
            throw IllegalArgumentException("ParameterizedType error")
        }
    }

    open fun getViewModel(activity: AppCompatActivity,clazz: Class<VM>): VM {
        val factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application)
        return ViewModelProvider(activity,factory)[clazz]
    }

    override fun lifecycleOwner(): LifecycleOwner {
        return this
    }
    public open fun openNavigation(event: NavigationEvent) {
        if (event.navType == NavigationEvent.Nav_Type_Activity) {
            val intent = Intent(this, event.clazz)
            if (event.bundle != null) {
                intent.putExtras(event.bundle)
            }
            if(event.isClearAll){
                ActivityManager.getInstance().finishAll()
            }else{
                if(event.isCloseSelf){
                    finish()
                }
            }
            if (event.reqCode > 0) {
                startActivityForResult(intent, event.reqCode)
            } else {
                startActivity(intent)
            }




        }
    }
    fun toastShortShow(text: String?) {
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
    }
    fun  isPageDesotryed():Boolean{
        return isFinishing|| isDestroyed
    }

    private var exitTime: Long = 0
    override fun onBackPressed() {
        if (ActivityManager.getInstance().count==1){
            if((System.currentTimeMillis() - exitTime) > 2000){
                exitTime=System.currentTimeMillis()
                Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show()
            }else{
                super.onBackPressed()
                LogUtils.d("framework","${this.javaClass.name}=======ShutDownEvent")
                EventBus.getDefault().post(ShutDownEvent())
                ktxRunOnUiThreadDelay {
                    exitProcess(0)
                }
            }

        }else{
            super.onBackPressed()
        }
    }

    override fun onStop() {
        super.onStop()
        LogUtils.d("framework","${this.javaClass.name}=======onStop")
    }


    override fun onResume() {
        super.onResume()
        LogUtils.d("framework","${this.javaClass.name}=======onResume")
    }

    override fun onPause() {
        super.onPause()
        LogUtils.d("framework","${this.javaClass.name}=======onPause")
    }

}